package com.bestcem.xm.qdes.service;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bestcem.xm.common.core.exception.BusinessException;
import com.bestcem.xm.common.core.uitls.SignUtil;
import com.bestcem.xm.component.mybatis.service.IXmService;
import com.bestcem.xm.qdes.controller.param.QuestionRestNoParam;
import com.bestcem.xm.qdes.entity.QdesProject;
import com.bestcem.xm.qdes.entity.QdesQstruct;
import com.bestcem.xm.qdes.entity.QdesQuestion;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.util.ObjectUtils;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.bestcem.xm.qdes.util.QstructConstant.*;

public interface QdesQuestionService extends IXmService<QdesQuestion> {

    /**
     * 递归方法填充题目
     * G  Q  O  依次，应该最大就3层，依次是组、问题、选项
     *
     * @param qMap
     * @param qstructsDataJson
     */
    default void fillData(Map<Integer, JSONObject> qMap, JSONObject qstructsDataJson) {
        JSONArray items = qstructsDataJson.getJSONArray("items");
        if (items == null) {
            return;
        }
        for (Object o : items) {
            JSONObject item = (JSONObject) o;
            String type = item.getString("type");
            if (StrUtil.isNotEmpty(type) && "G".equals(type)) {
                fillData(qMap, item);
            } else {
                Integer gid = item.getInteger("gid");
                if (gid != null && qMap.get(gid) != null) {
                    item.putAll(qMap.get(gid));
                }
            }
        }
    }

    /**
     * 附件加签
     *
     * @param map
     * @param gid
     * @param data
     * @author chenglong.yue <chenglong.yue@idiaoyan.com>
     * @date 2022/10/9 11:31
     */
    default void genQuestionSign(Map<String, String> map, String gid, JSONObject data) {
        //"attachData":{"openAttach":true,"allowNotUpload":false,"onlyImage":true,"showThumbnail":true,"minNum":1,"maxNum":1,"minSize":0,"maxSize":50,"openOAttach":true,"allowONotUpload":false,"onlyOImage":true,"showOThumbnail":true,"minONum":1,"maxONum":1,"minOSize":0,"maxOSize":50,"excludeOptionList":[],"allowSameName":true}
        JSONObject attachData = data.getJSONObject(ATTACH_DATA);
        if (!ObjectUtils.isEmpty(attachData) && attachData.containsKey(OPEN_ATTACH) && attachData.getBoolean(OPEN_ATTACH)) {
            HashMap<String, Object> signMap = new HashMap<String, Object>() {{
                put("pid", map.get("projectId"));
                put("version", map.get("version"));
                put("qid", gid);
                //后面几个没从接口参数里面取？
                put("openAttach", false);
                put("onlyImage", false);
                put("minNum", "");
                put("maxNum", "");
                put("minSize", "");
                put("maxSize", "");
            }};
            attachData.put(SIG, SignUtil.genSign(signMap, map.get("secretKey")));
        }
    }

    /**
     * 通用递归函数,无数据库操作
     *
     * @param item
     * @param qdict
     * @param questions
     * @author chenglong.yue <chenglong.yue@idiaoyan.com>
     * @date 2022/10/9 10:53
     */
    default void getQstructQuestions(JSONObject item, Map<Integer, JSONObject> qdict, JSONArray questions) {
        if (ObjectUtils.isEmpty(item) || item.isEmpty()) {
            return;
        }
        String type = item.getString("type");
        if (StringUtils.isEmpty(type)) {
            Integer gid = item.getInteger("gid");
            if (gid != null) {
                JSONObject item2 = qdict.get(gid);
                if (item2 != null) {
                    questions.add(item2);
                }
            }
        } else if ("Q".equals(type)) {
            questions.add(item);
        } else if ("G".equals(type)) {
            if (item.get("items") == null) {
                throw new BusinessException(String.format("group[gid=%s] must have :items field", item.get("gid")));
            }
            item.getJSONArray("items").forEach(it -> {
                if (it instanceof JSONObject) {
                    JSONObject item3 = (JSONObject) it;
                    getQstructQuestions(item3, qdict, questions);
                } else {
                    // items 也会有这种[3,4]
                    if (NumberUtils.isDigits(it.toString())) {
                        JSONObject item4 = qdict.get(Integer.valueOf(it.toString()));
                        if (item4 != null) {
                            questions.add(item4);
                        }
                    }
                }
            });
        }
    }

    void addOneQuestion(String structId, JSONObject param);

    int delOneQuestion(String structId, String gid);

    int delQuestions(String structId, JSONObject param);

    int resetQuestionNo(QdesQstruct qstruct, QuestionRestNoParam param);

    void checkCid(JSONObject param);

    void checkOid(JSONObject param);

    QdesQstruct checkAndGetQstruct(String id);

    QdesProject checkAndGetProject(QdesQstruct struct);

    QdesQuestion checkAndGetQuestion(String structId, String gid);

    void checkOptionsGroupEffect(JSONObject data, QdesQstruct struct, String structId, String gid);

    void checkOptionOrigin(JSONObject data, QdesQuestion question, String structId, String gid);

    void updateQuestion(String structId, String gid, JSONObject data, QdesQuestion question, QdesQstruct struct);

    void updateQuestions(String structId, List<String> gids, List<JSONObject> datas, List<QdesQuestion> questions, QdesQstruct struct, int count);

    void updateQstruct(QdesQstruct struct, QdesProject project, JSONObject param);

    List<QdesQuestion> getQuestionList(String structID, Collection<?> gids);

    int calculateTimecost(JSONObject data);
}
